/**
 * 本地存储工具
 */

import { safeJsonParse, safeJsonStringify } from './util.js'

/**
 * 存储键名常量
 */
export const STORAGE_KEYS = {
  USER_INFO: 'userInfo',
  CATEGORIES: 'categories',
  BILLS_CACHE: 'billsCache',
  SETTINGS: 'settings',
  BUDGET_CACHE: 'budgetCache',
  STATISTICS_CACHE: 'statisticsCache',
  DRAFT_BILL: 'draftBill',
  SEARCH_HISTORY: 'searchHistory',
  THEME: 'theme',
  LAST_SYNC_TIME: 'lastSyncTime'
}

/**
 * 存储工具类
 */
class Storage {
  /**
   * 设置存储项
   * @param {string} key - 键名
   * @param {any} value - 值
   * @param {number} expire - 过期时间（毫秒），可选
   * @returns {boolean} 是否成功
   */
  setItem(key, value, expire) {
    try {
      const data = {
        value,
        timestamp: Date.now(),
        expire: expire ? Date.now() + expire : null
      }
      
      wx.setStorageSync(key, safeJsonStringify(data))
      return true
    } catch (error) {
      console.error('存储设置失败:', error)
      return false
    }
  }

  /**
   * 获取存储项
   * @param {string} key - 键名
   * @param {any} defaultValue - 默认值
   * @returns {any} 存储的值
   */
  getItem(key, defaultValue = null) {
    try {
      const dataStr = wx.getStorageSync(key)
      if (!dataStr) {
        return defaultValue
      }

      const data = safeJsonParse(dataStr)
      if (!data || typeof data !== 'object') {
        return defaultValue
      }

      // 检查是否过期
      if (data.expire && Date.now() > data.expire) {
        this.removeItem(key)
        return defaultValue
      }

      return data.value !== undefined ? data.value : defaultValue
    } catch (error) {
      console.error('存储获取失败:', error)
      return defaultValue
    }
  }

  /**
   * 移除存储项
   * @param {string} key - 键名
   * @returns {boolean} 是否成功
   */
  removeItem(key) {
    try {
      wx.removeStorageSync(key)
      return true
    } catch (error) {
      console.error('存储移除失败:', error)
      return false
    }
  }

  /**
   * 清空所有存储
   * @returns {boolean} 是否成功
   */
  clear() {
    try {
      wx.clearStorageSync()
      return true
    } catch (error) {
      console.error('存储清空失败:', error)
      return false
    }
  }

  /**
   * 获取存储信息
   * @returns {object} 存储信息
   */
  getInfo() {
    try {
      return wx.getStorageInfoSync()
    } catch (error) {
      console.error('获取存储信息失败:', error)
      return { keys: [], currentSize: 0, limitSize: 0 }
    }
  }

  /**
   * 检查键是否存在
   * @param {string} key - 键名
   * @returns {boolean} 是否存在
   */
  hasKey(key) {
    try {
      const info = this.getInfo()
      return info.keys.includes(key)
    } catch (error) {
      return false
    }
  }

  /**
   * 获取所有键名
   * @returns {Array} 键名数组
   */
  getAllKeys() {
    try {
      const info = this.getInfo()
      return info.keys || []
    } catch (error) {
      return []
    }
  }

  /**
   * 批量设置
   * @param {object} items - 键值对对象
   * @returns {boolean} 是否全部成功
   */
  setItems(items) {
    let success = true
    for (const [key, value] of Object.entries(items)) {
      if (!this.setItem(key, value)) {
        success = false
      }
    }
    return success
  }

  /**
   * 批量获取
   * @param {Array} keys - 键名数组
   * @param {any} defaultValue - 默认值
   * @returns {object} 键值对对象
   */
  getItems(keys, defaultValue = null) {
    const result = {}
    keys.forEach(key => {
      result[key] = this.getItem(key, defaultValue)
    })
    return result
  }

  /**
   * 批量移除
   * @param {Array} keys - 键名数组
   * @returns {boolean} 是否全部成功
   */
  removeItems(keys) {
    let success = true
    keys.forEach(key => {
      if (!this.removeItem(key)) {
        success = false
      }
    })
    return success
  }
}

// 创建存储实例
const storage = new Storage()

/**
 * 用户信息存储
 */
export const userStorage = {
  /**
   * 保存用户信息
   * @param {object} userInfo - 用户信息
   */
  setUserInfo(userInfo) {
    return storage.setItem(STORAGE_KEYS.USER_INFO, userInfo)
  },

  /**
   * 获取用户信息
   * @returns {object|null} 用户信息
   */
  getUserInfo() {
    return storage.getItem(STORAGE_KEYS.USER_INFO)
  },

  /**
   * 清除用户信息
   */
  clearUserInfo() {
    return storage.removeItem(STORAGE_KEYS.USER_INFO)
  },

  /**
   * 检查是否已登录
   * @returns {boolean} 是否已登录
   */
  isLoggedIn() {
    const userInfo = this.getUserInfo()
    return userInfo && userInfo.openid
  }
}

/**
 * 分类数据存储
 */
export const categoryStorage = {
  /**
   * 保存分类数据
   * @param {Array} categories - 分类数组
   * @param {number} expire - 过期时间，默认24小时
   */
  setCategories(categories, expire = 24 * 60 * 60 * 1000) {
    return storage.setItem(STORAGE_KEYS.CATEGORIES, categories, expire)
  },

  /**
   * 获取分类数据
   * @returns {Array} 分类数组
   */
  getCategories() {
    return storage.getItem(STORAGE_KEYS.CATEGORIES, [])
  },

  /**
   * 清除分类缓存
   */
  clearCategories() {
    return storage.removeItem(STORAGE_KEYS.CATEGORIES)
  },

  /**
   * 根据类型获取分类
   * @param {string} type - 分类类型 income/expense
   * @returns {Array} 分类数组
   */
  getCategoriesByType(type) {
    const categories = this.getCategories()
    return categories.filter(cat => cat.type === type)
  }
}

/**
 * 账单缓存存储
 */
export const billStorage = {
  /**
   * 保存账单缓存
   * @param {string} cacheKey - 缓存键
   * @param {Array} bills - 账单数组
   * @param {number} expire - 过期时间，默认5分钟
   */
  setBillsCache(cacheKey, bills, expire = 5 * 60 * 1000) {
    const key = `${STORAGE_KEYS.BILLS_CACHE}_${cacheKey}`
    return storage.setItem(key, bills, expire)
  },

  /**
   * 获取账单缓存
   * @param {string} cacheKey - 缓存键
   * @returns {Array} 账单数组
   */
  getBillsCache(cacheKey) {
    const key = `${STORAGE_KEYS.BILLS_CACHE}_${cacheKey}`
    return storage.getItem(key, [])
  },

  /**
   * 清除账单缓存
   * @param {string} cacheKey - 缓存键，不传则清除所有
   */
  clearBillsCache(cacheKey) {
    if (cacheKey) {
      const key = `${STORAGE_KEYS.BILLS_CACHE}_${cacheKey}`
      return storage.removeItem(key)
    } else {
      // 清除所有账单缓存
      const allKeys = storage.getAllKeys()
      const billsCacheKeys = allKeys.filter(key => key.startsWith(STORAGE_KEYS.BILLS_CACHE))
      return storage.removeItems(billsCacheKeys)
    }
  }
}

/**
 * 草稿存储
 */
export const draftStorage = {
  /**
   * 保存账单草稿
   * @param {object} draftData - 草稿数据
   */
  setDraftBill(draftData) {
    return storage.setItem(STORAGE_KEYS.DRAFT_BILL, draftData)
  },

  /**
   * 获取账单草稿
   * @returns {object|null} 草稿数据
   */
  getDraftBill() {
    return storage.getItem(STORAGE_KEYS.DRAFT_BILL)
  },

  /**
   * 清除账单草稿
   */
  clearDraftBill() {
    return storage.removeItem(STORAGE_KEYS.DRAFT_BILL)
  },

  /**
   * 检查是否有草稿
   * @returns {boolean} 是否有草稿
   */
  hasDraftBill() {
    const draft = this.getDraftBill()
    return draft && Object.keys(draft).length > 0
  }
}

/**
 * 设置存储
 */
export const settingsStorage = {
  /**
   * 保存设置
   * @param {object} settings - 设置对象
   */
  setSettings(settings) {
    return storage.setItem(STORAGE_KEYS.SETTINGS, settings)
  },

  /**
   * 获取设置
   * @returns {object} 设置对象
   */
  getSettings() {
    return storage.getItem(STORAGE_KEYS.SETTINGS, {})
  },

  /**
   * 更新单个设置
   * @param {string} key - 设置键
   * @param {any} value - 设置值
   */
  updateSetting(key, value) {
    const settings = this.getSettings()
    settings[key] = value
    return this.setSettings(settings)
  },

  /**
   * 获取单个设置
   * @param {string} key - 设置键
   * @param {any} defaultValue - 默认值
   * @returns {any} 设置值
   */
  getSetting(key, defaultValue = null) {
    const settings = this.getSettings()
    return settings[key] !== undefined ? settings[key] : defaultValue
  },

  /**
   * 清除设置
   */
  clearSettings() {
    return storage.removeItem(STORAGE_KEYS.SETTINGS)
  }
}

/**
 * 搜索历史存储
 */
export const searchStorage = {
  /**
   * 添加搜索历史
   * @param {string} keyword - 搜索关键词
   * @param {number} maxCount - 最大保存数量
   */
  addSearchHistory(keyword, maxCount = 10) {
    if (!keyword || keyword.trim() === '') return false

    let history = this.getSearchHistory()
    
    // 移除重复项
    history = history.filter(item => item !== keyword)
    
    // 添加到开头
    history.unshift(keyword)
    
    // 限制数量
    if (history.length > maxCount) {
      history = history.slice(0, maxCount)
    }
    
    return storage.setItem(STORAGE_KEYS.SEARCH_HISTORY, history)
  },

  /**
   * 获取搜索历史
   * @returns {Array} 搜索历史数组
   */
  getSearchHistory() {
    return storage.getItem(STORAGE_KEYS.SEARCH_HISTORY, [])
  },

  /**
   * 清除搜索历史
   */
  clearSearchHistory() {
    return storage.removeItem(STORAGE_KEYS.SEARCH_HISTORY)
  },

  /**
   * 删除单个搜索历史
   * @param {string} keyword - 要删除的关键词
   */
  removeSearchHistory(keyword) {
    let history = this.getSearchHistory()
    history = history.filter(item => item !== keyword)
    return storage.setItem(STORAGE_KEYS.SEARCH_HISTORY, history)
  }
}

/**
 * 主题存储
 */
export const themeStorage = {
  /**
   * 设置主题
   * @param {string} theme - 主题名称
   */
  setTheme(theme) {
    return storage.setItem(STORAGE_KEYS.THEME, theme)
  },

  /**
   * 获取主题
   * @returns {string} 主题名称
   */
  getTheme() {
    return storage.getItem(STORAGE_KEYS.THEME, 'light')
  },

  /**
   * 切换主题
   * @returns {string} 新的主题名称
   */
  toggleTheme() {
    const currentTheme = this.getTheme()
    const newTheme = currentTheme === 'light' ? 'dark' : 'light'
    this.setTheme(newTheme)
    return newTheme
  }
}

/**
 * 同步时间存储
 */
export const syncStorage = {
  /**
   * 设置最后同步时间
   * @param {string} type - 同步类型
   * @param {number} timestamp - 时间戳
   */
  setLastSyncTime(type, timestamp = Date.now()) {
    const syncTimes = storage.getItem(STORAGE_KEYS.LAST_SYNC_TIME, {})
    syncTimes[type] = timestamp
    return storage.setItem(STORAGE_KEYS.LAST_SYNC_TIME, syncTimes)
  },

  /**
   * 获取最后同步时间
   * @param {string} type - 同步类型
   * @returns {number} 时间戳
   */
  getLastSyncTime(type) {
    const syncTimes = storage.getItem(STORAGE_KEYS.LAST_SYNC_TIME, {})
    return syncTimes[type] || 0
  },

  /**
   * 检查是否需要同步
   * @param {string} type - 同步类型
   * @param {number} interval - 同步间隔（毫秒）
   * @returns {boolean} 是否需要同步
   */
  needSync(type, interval = 5 * 60 * 1000) {
    const lastSyncTime = this.getLastSyncTime(type)
    return Date.now() - lastSyncTime > interval
  }
}

/**
 * 缓存管理器
 */
export const cacheManager = {
  /**
   * 清除所有缓存
   */
  clearAllCache() {
    billStorage.clearBillsCache()
    categoryStorage.clearCategories()
    return storage.removeItem(STORAGE_KEYS.STATISTICS_CACHE)
  },

  /**
   * 清除过期缓存
   */
  clearExpiredCache() {
    const allKeys = storage.getAllKeys()
    let clearedCount = 0
    
    allKeys.forEach(key => {
      const value = storage.getItem(key)
      if (value === null) {
        // 如果获取到null，说明缓存已过期被自动清除
        clearedCount++
      }
    })
    
    return clearedCount
  },

  /**
   * 获取缓存统计信息
   * @returns {object} 缓存统计
   */
  getCacheStats() {
    const info = storage.getInfo()
    const allKeys = storage.getAllKeys()
    
    const stats = {
      totalKeys: allKeys.length,
      currentSize: info.currentSize,
      limitSize: info.limitSize,
      usageRate: info.limitSize > 0 ? (info.currentSize / info.limitSize * 100).toFixed(2) : 0,
      keysByType: {}
    }
    
    // 按类型统计键数量
    Object.values(STORAGE_KEYS).forEach(keyType => {
      const count = allKeys.filter(key => key.startsWith(keyType)).length
      if (count > 0) {
        stats.keysByType[keyType] = count
      }
    })
    
    return stats
  },

  /**
   * 存储空间清理
   * @param {number} targetUsageRate - 目标使用率（百分比）
   */
  cleanup(targetUsageRate = 80) {
    const stats = this.getCacheStats()
    
    if (stats.usageRate <= targetUsageRate) {
      return { cleaned: false, message: '存储空间充足，无需清理' }
    }
    
    // 清理策略：优先清理缓存数据
    let cleanedKeys = 0
    
    // 1. 清理账单缓存
    billStorage.clearBillsCache()
    cleanedKeys += stats.keysByType[STORAGE_KEYS.BILLS_CACHE] || 0
    
    // 2. 清理统计缓存
    storage.removeItem(STORAGE_KEYS.STATISTICS_CACHE)
    cleanedKeys++
    
    // 3. 清理分类缓存
    categoryStorage.clearCategories()
    cleanedKeys++
    
    return {
      cleaned: true,
      cleanedKeys,
      message: `已清理 ${cleanedKeys} 个缓存项`
    }
  }
}

// 默认导出存储实例
export default storage